package dondeestamitransporte.mundo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

import com.google.android.gms.maps.model.LatLng;

import dondeestamitransporte.actividadesPasajero.MisRutasActivity;
import dondeestamitransporte.manejadorPersistencia.Persistencia;
import dondeestamitrasnporte.protocolo.ManejadorProtocolo;
import dondeestamitrasnporte.protocolo.Paradero;

import android.content.Context;
import android.content.Intent;
import android.util.Log;


public class MundoPasajero 
{
	private Persistencia persistencia;

	public String[][] miSemanaPasajero;

	public int[][] alarmas;

	public ArrayList<RutaPasajero> rutasPasajero;

	public boolean datosCargados = false;

	public boolean creandoRutaPorEstadisticas = false;

	private boolean seAgregoRutaNueva = false;

	public boolean isSeAgregoRutaNueva() {
		return seAgregoRutaNueva;
	}

	public void setSeAgregoRutaNueva(boolean seAgregoRutaNueva) {
		this.seAgregoRutaNueva = seAgregoRutaNueva;
	}

	private ArrayList<Paradero> paraderos = new ArrayList<Paradero>();

	private ArrayList<LatLng> dibujo = new ArrayList<LatLng>();

	private String nombreParadero = "";

	private String nombreEnviante ="";




	/**
	 * Este objeto es singleton
	 */
	private static MundoPasajero instance = new MundoPasajero();

	private MundoPasajero()
	{}

	public static MundoPasajero getInstance()
	{
		return instance;
	}

	public void establecerPersistencia(Context context)
	{
		persistencia = new Persistencia(context);
		persistencia.cargar(this);
		refrescarSemanaPorCambioDeDia();
		datosCargados = true;
	}

	/**
	 * Metodo que devuelve la posicion en el arreglo de rutas de la ruta en la que se debe estar montando el usuario
	 * @return
	 */
	public int darPosicionSiguienteRutaEnSalir()
	{
		int respuesta = 0;
		Calendar c = Calendar.getInstance(TimeZone.getDefault());
		int diaDeLaSemanaActual = (c.get(Calendar.DAY_OF_WEEK)-1);
		diaDeLaSemanaActual = (diaDeLaSemanaActual -1)%7;
		if(diaDeLaSemanaActual<0)
		{
			diaDeLaSemanaActual = diaDeLaSemanaActual+7;
		}

		RutaPasajero ruta1 = darRuta( miSemanaPasajero[diaDeLaSemanaActual][0]);

		RutaPasajero ruta2 = darRuta( miSemanaPasajero[diaDeLaSemanaActual][1]);

		if(ruta1==null && ruta2==null)
		{
			return 0;
		}
		else if (ruta1==null)
		{
			for(int i = 0; i < rutasPasajero.size();i++)
			{

				if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(ruta2.getNombre()))
				{
					respuesta = i;
					i = rutasPasajero.size();
				}
			}

			return respuesta;

		}
		else if (ruta2==null)
		{
			for(int i = 0; i < rutasPasajero.size();i++)
			{

				if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(ruta1.getNombre()))
				{
					respuesta = i;
					i = rutasPasajero.size();
				}
			}

			return respuesta;
		}

		else if(ruta1.CompareTo(ruta2) >= 0)
		{

			for(int i = 0; i < rutasPasajero.size();i++)
			{

				if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(ruta1.getNombre()))
				{
					respuesta = i;
					i = rutasPasajero.size();
				}
			}

			return respuesta;

		}
		else
		{
			for(int i = 0; i < rutasPasajero.size();i++)
			{

				if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(ruta2.getNombre()))
				{
					respuesta = i;
					i = rutasPasajero.size();
				}
			}

			return respuesta;

		}


	}

	public void agregarEstadistica(int posicionRuta)
	{
		String estadistica = calcularEstadistica();
		persistencia.agregarEstadistica(rutasPasajero.get(posicionRuta).getNombre(), rutasPasajero.get(posicionRuta).getNombreParadero(), estadistica);
		rutasPasajero.get(posicionRuta).setHoraEsperada(persistencia.darHoraEsperadaDeSalida(rutasPasajero.get(posicionRuta).getNombre()));
	}



	/**
	 * Metodo que agrega una nueva ruta
	 * @param ruta
	 */
	public void agregarRuta(RutaPasajero ruta)
	{

		persistencia.agregarRuta(ruta);
		rutasPasajero.add(ruta);
	}

	/**
	 * Metodo que verifica si el nombre de la ruta ya se esta utilizando
	 * @param nombre
	 * @return
	 */
	public boolean nombreYaUtilizado(String nombre)
	{
		boolean respuesta = false;
		for(int i = 0; i < rutasPasajero.size();i++)
		{

			if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(nombre))
			{
				respuesta = true;
				i = rutasPasajero.size();
			}
		}

		return respuesta;


	}


	/**
	 * Metodo que actualiza una ruta.
	 * @param ruta
	 * @param nombreRutaVieja
	 */
	public void actualizarRuta(RutaPasajero ruta, String nombreRutaVieja, String paraderoViejo)
	{
		persistencia.actualizarRuta(ruta, nombreRutaVieja,paraderoViejo);



		for(int i = 0; i < rutasPasajero.size();i++)
		{
			if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(nombreRutaVieja))
			{
				rutasPasajero.set(i, ruta);
				i = rutasPasajero.size();
			}
		}

		for(int i =0; i <7;i++)
		{
			if(miSemanaPasajero[i][0]!=null && miSemanaPasajero[i][0].equalsIgnoreCase(nombreRutaVieja) )
			{
				miSemanaPasajero[i][0]=ruta.getNombre();
			}
			if(miSemanaPasajero[i][1]!=null && miSemanaPasajero[i][1].equalsIgnoreCase(nombreRutaVieja) )
			{
				miSemanaPasajero[i][1]=ruta.getNombre();
			}
		}

		refrescarSemana();
		persistencia.actualizarSemana(miSemanaPasajero, alarmas);


	}

	/**
	 * Metodo que elimina una ruta.
	 */
	public void eliminarrRuta(int posicionRuta)
	{
		if(rutasPasajero.size()>0)
		{
			RutaPasajero  eliminar = rutasPasajero.get(posicionRuta);

			String nombreRutaVieja = eliminar.getNombre();
			for(int i =0; i <7;i++)
			{
				if(miSemanaPasajero[i][0]!=null && miSemanaPasajero[i][0].equalsIgnoreCase(nombreRutaVieja) )
				{
					miSemanaPasajero[i][0]=null;
					alarmas[i][0]=0;
				}
				if(miSemanaPasajero[i][1]!=null && miSemanaPasajero[i][1].equalsIgnoreCase(nombreRutaVieja) )
				{
					miSemanaPasajero[i][1]=null;
					alarmas[i][1]=0;
				}
			}


			persistencia.eliminarRuta(eliminar.getNombre(), eliminar.getNombreParadero());

			rutasPasajero.remove(posicionRuta);

		}
	}

	public RutaPasajero darRuta(String nombre)
	{
		RutaPasajero respuesta = null;
		for(int i = 0; i < rutasPasajero.size();i++)
		{

			if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(nombre))
			{
				respuesta = rutasPasajero.get(i);
				i = rutasPasajero.size();
			}
		}

		return respuesta;

	}

	public int darPosicionRuta(String nombre)
	{
		int respuesta = 0;
		for(int i = 0; i < rutasPasajero.size();i++)
		{

			if(rutasPasajero.get(i).getNombre().equalsIgnoreCase(nombre))
			{
				respuesta = i;
				i = rutasPasajero.size();
			}
		}

		return respuesta;

	}

	public List<String> darNombresRutas()
	{
		List<String> respuesta = new ArrayList<String>();
		for(int i = 0; i <rutasPasajero.size();i++)
		{
			respuesta.add(rutasPasajero.get(i).getNombre());
		}

		return respuesta;
	}

	public String darHoraAproxiamdaDeSalida(int posicionRuta)
	{
		String horaAprox = persistencia.darHoraEsperadaDeSalida(rutasPasajero.get(posicionRuta).getNombre());
		String adicion = "";
		String[] temp = horaAprox.split(":");
		int horasLlegada = Integer.parseInt(temp[0]);
		int minutosLlegada = Integer.parseInt(temp[1]);

		int minutos = minutosLlegada - (rutasPasajero.get(posicionRuta).getTiempoDesplazamiento());

		if(minutos<0)
		{
			horasLlegada--;
			minutos=minutos+60;
		}
		if(horasLlegada<0)
		{
			horasLlegada = horasLlegada+24;
			adicion=" (Del dia Anterior)";
		}

		if(minutos<10)
		{
			return horasLlegada +":0" + minutos + adicion;
		}
		else
		{
			return horasLlegada +":" + minutos + adicion;
		}

	}

	public void refrescarSemanaPorCambioDeDia()
	{
		//los datos tomados en el formato MM:DD:S donde ss el dia de la semana. de 0 a 6. TEXT

		Calendar c = Calendar.getInstance(TimeZone.getDefault());
		int diaDeLaSemanaActual = (c.get(Calendar.DAY_OF_WEEK)-1);
		int mesActual = c.get(c.MONTH);
		int diaActual = c.get(c.DAY_OF_MONTH);

		String ultimaActualizacion = persistencia.darUltimaActualizacion();
		if(ultimaActualizacion==null)
		{
			alarmas = new int[7][2];
			String[][] semana = new String[7][2];

			for(int i =0; i<7;i++)
			{
				semana[i][0] = null;
				semana[i][1] = null;
			}

			for(int i =0; i <7;i++)
			{
				for(int j =0;j<rutasPasajero.size();j++)
				{
					if(rutasPasajero.get(j).getSemanaDeLaRuta()[i] == 1)
					{
						if(semana[i][0] == null)
						{
							semana[i][0] = rutasPasajero.get(j).getNombre();
						}
						else if(semana[i][1] == null  && !miSemanaPasajero[i][0].equalsIgnoreCase(rutasPasajero.get(j).getNombre()))
						{
							semana[i][1] = rutasPasajero.get(j).getNombre();
						}
					}

				}
			}

			miSemanaPasajero = semana;

		}
		else
		{
			String[] temp = ultimaActualizacion.split(":");

			int mesUltima = Integer.parseInt(temp[0]);
			int diaUltima = Integer.parseInt(temp[1]);
			int diaSemanaUltima = Integer.parseInt(temp[2]);


			if(Math.abs(mesUltima-mesActual)>0 || Math.abs(diaUltima-diaActual)>=7)
			{
				alarmas = new int[7][2];
				String[][] semana = new String[7][2];

				for(int i =0; i<7;i++)
				{
					semana[i][0] = null;
					semana[i][1] = null;
				}

				for(int i =0; i <7;i++)
				{
					for(int j =0;j<rutasPasajero.size();j++)
					{
						if(rutasPasajero.get(j).getSemanaDeLaRuta()[i] == 1)
						{
							if(semana[i][0] == null)
							{
								semana[i][0] = rutasPasajero.get(j).getNombre();
							}
							else if(semana[i][1] == null && !miSemanaPasajero[i][0].equalsIgnoreCase(rutasPasajero.get(j).getNombre()))
							{
								semana[i][1] = rutasPasajero.get(j).getNombre();
							}
						}

					}
				}

				miSemanaPasajero = semana;

			}
			else
			{

				int progreso = diaSemanaUltima;
				while(progreso!=diaDeLaSemanaActual)
				{
					for(int j =0;j<rutasPasajero.size();j++)
					{

						if(rutasPasajero.get(j).getSemanaDeLaRuta()[progreso] == 1)
						{
							if(miSemanaPasajero[progreso][0] == null)
							{
								miSemanaPasajero[progreso][0] = rutasPasajero.get(j).getNombre();
							}
							else if(miSemanaPasajero[progreso][1] == null  && !miSemanaPasajero[progreso][0].equalsIgnoreCase(rutasPasajero.get(j).getNombre()))
							{
								miSemanaPasajero[progreso][1] = rutasPasajero.get(j).getNombre();
							}
						}

					}

					alarmas[progreso][0]=0;
					alarmas[progreso][1]=0;

					progreso++;
					progreso = progreso%7;
					if(progreso<0)
					{
						progreso = progreso+7;
					}

				}
			}
		}


		persistencia.actualizarSemana(miSemanaPasajero, alarmas);
		persistencia.actializarUltimaFecha();


	}

	public void refrescarSemana()
	{



		for(int i =0; i <7;i++)
		{
			if(rutasPasajero!=null)
			{
				for(int j =0;j<rutasPasajero.size();j++)
				{
					if(rutasPasajero.get(j).getSemanaDeLaRuta()[i] == 1)
					{
						if(miSemanaPasajero[i][0] == null)
						{
							miSemanaPasajero[i][0] = rutasPasajero.get(j).getNombre();
							alarmas[i][0]=0;

						}
						else if(miSemanaPasajero[i][1] == null && !miSemanaPasajero[i][0].equalsIgnoreCase(rutasPasajero.get(j).getNombre()) )
						{
							miSemanaPasajero[i][1] = rutasPasajero.get(j).getNombre();
							alarmas[i][1]=0;
						}
					}

				}
			}
		}

		persistencia.actualizarSemana(miSemanaPasajero, alarmas);


	}

	public void asignarRutaAUnDia(int posicionRuta, int diaSemana, int numeroDeRuta)
	{
		alarmas[diaSemana][numeroDeRuta]=0;
		miSemanaPasajero[diaSemana][numeroDeRuta] = rutasPasajero.get(posicionRuta).getNombre();
		persistencia.actualizarSemana(miSemanaPasajero, alarmas);
	}

	public void asignarAlarma(int tiempoAlarma, int diaSemana, int posicion)
	{
		alarmas[diaSemana][posicion]=tiempoAlarma;
		persistencia.actualizarSemana(miSemanaPasajero, alarmas);
	}

	public void agregarNuevoParadero(String nombreRuta, Paradero para, int posicion)
	{
		persistencia.agregarNuevoParadero(nombreRuta, para, posicion);

	}
	

	public void agregarParaderosAlternos(String nombreRuta, ArrayList<Paradero> paraderos)
	{
		persistencia.agregarParaderosAlternos(nombreRuta, paraderos);
	}

	public void agregarEstadisticasDeParadero(String nombreRuta, Paradero para)
	{
		persistencia.agregarEstadisticasDeParadero(nombreRuta, para);
	}

	public void actualizarCoordenadasParadero( String NombreRauta, Paradero para)
	{
		persistencia.actualizarCoordenadasParadero(NombreRauta,para);
	}
	/**
	 * Metodo que calcula la estadistica actual para ser insertada como dato
	 * @return
	 */
	private String calcularEstadistica() 
	{
		Calendar c = Calendar.getInstance(TimeZone.getDefault());
		int diaDeLaSemanaActual = (c.get(Calendar.DAY_OF_WEEK)-1);
		int minutosActuales = c.get(c.MINUTE);
		int horasActuales = c.get(c.HOUR_OF_DAY);
		int mes = c.get(c.MONTH);
		int dia = c.get(c.DAY_OF_MONTH);

		diaDeLaSemanaActual = (diaDeLaSemanaActual -1)%7;
		if(diaDeLaSemanaActual<0)
		{
			diaDeLaSemanaActual = diaDeLaSemanaActual+7;
		}

		//EL FORMATO ES formato MM:DD:S:HH:MM TEXT




		return mes+":"+dia+":"+diaDeLaSemanaActual+":"+horasActuales+":"+minutosActuales;
	}

	public boolean YaExisteEseParaderoParadero(String nombreRuta,String para)
	{


		return persistencia.YaExisteEseParadero(nombreRuta,para);
	}
	
	public boolean YaTieneCoordenadasElParadero(String nombreRuta, String para)
	{
		
		return persistencia.YaTieneCoordenadasElParadero(nombreRuta, para);
	}



	public boolean SePuedeDibujar(String ruta)
	{
		return persistencia.SePuedeDibujar(ruta);
	}



	public void agregarDibujo(String nombreRuta, ArrayList<LatLng> coordenadas)
	{
		persistencia.agregarDibujo(nombreRuta, coordenadas);
	}

	public ArrayList<LatLng> darDibujo(String nombreRuta)
	{
		return persistencia.darDibujo(nombreRuta);
	}


	public ArrayList<Paradero> darTodosParaderos(String nombreRuta)
	{

		return persistencia.darParaderos(nombreRuta);
	}

	public Paradero darParadero(String nombreRuta, String nombreParadero)
	{
		return persistencia.darParadero(nombreRuta, nombreParadero);
	}


	public void prepararParaIngresoInformacion(String NombreEnviante, String mensaje)
	{
		creandoRutaPorEstadisticas = true;
		nombreEnviante = NombreEnviante;
		Object[] ob = ManejadorProtocolo.desencriptarString(mensaje);
		paraderos = (ArrayList<Paradero>) ob[0];
		dibujo = (ArrayList<LatLng>) ob[1];



	}

	public void terminarIngresoInformacion(RutaPasajero rut)
	{

		if(paraderos.size()>0)
		{
			for(int i = 0; i < paraderos.size(); i++)
			{
				if(nombreParadero.equals(paraderos.get(i).getNombre()))
				{
					if(seAgregoRutaNueva)
					{
						agregarEstadisticasDeParadero(rut.getNombre(), paraderos.get(i));
						actualizarCoordenadasParadero(rut.getNombre(),paraderos.get(i));
						paraderos.remove(i);
					}
					else
					{

						paraderos.get(i).setNombre(rut.getNombreParadero());
						agregarEstadisticasDeParadero(rut.getNombre(), paraderos.get(i));
						actualizarCoordenadasParadero(rut.getNombre(),paraderos.get(i));
						paraderos.remove(i);
					}
				}
			}
			
			agregarParaderosAlternos(rut.getNombre(), paraderos);
			
		}
			




		agregarDibujo(rut.getNombre(), dibujo);

		creandoRutaPorEstadisticas=false;
		seAgregoRutaNueva=false;




	}
		
		

	public Persistencia getPersistencia() {
		return persistencia;
	}

	public void setPersistencia(Persistencia persistencia) {
		this.persistencia = persistencia;
	}

	public ArrayList<Paradero> getParaderos() {
		return paraderos;
	}

	public void setParaderos(ArrayList<Paradero> paraderos) {
		this.paraderos = paraderos;
	}

	public String getNombreParadero() {
		return nombreParadero;
	}

	public void setNombreParadero(String nombreParadero) {
		this.nombreParadero = nombreParadero;
	}

	public String getNombreEnviante() {
		return nombreEnviante;
	}

	public void setNombreEnviante(String nombreEnviante) {
		this.nombreEnviante = nombreEnviante;
	}




}
